package cn.com.anypay.manager.payment.service;

import cn.com.anypay.manager.payment.core.IPaymentChannel;
import cn.com.anypay.manager.payment.core.PaymentException;
import cn.com.anypay.manager.payment.dto.*;
import cn.com.anypay.manager.payment.manager.PaymentChannelManager;
import cn.com.anypay.manager.payment.manager.PaymentManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 统一支付服务 - 现在只依赖PaymentManager
 *
 * 提供对外的统一支付接口，屏蔽渠道差异
 *
 * @author AnyPay Team
 * @version 1.0
 * @since 2025-07-05
 */
@Service
public class PaymentService {

    private static final Logger logger = LoggerFactory.getLogger(PaymentService.class);

    @Autowired
    private PaymentManager paymentManager;

    /**
     * 初始化测试渠道 - 现在不需要了，由PaymentManager统一管理
     *
     * @throws PaymentException 初始化失败时抛出
     */
    public void initializeTestChannels() throws PaymentException {
        logger.debug("测试渠道已由PaymentManager统一初始化");
        logger.debug("测试渠道初始化完成，已注册 {} 个渠道", paymentManager.getChannelCount());
        logger.debug("ChannelTest1 支持的实现类型: {}", String.join(", ", paymentManager.getChannelManager().getChannelImplementationTypes("channeltest1")));

        // 打印所有渠道实现信息
        printAllChannelImplementationInfo();
    }

    /**
     * 创建支付
     *
     * @param request 支付请求
     * @return 支付结果
     * @throws PaymentException 支付创建失败时抛出
     */
    public PaymentResultDTO createPayment(PaymentRequestDTO request) throws PaymentException {
        if (request == null) {
            throw new PaymentException("INVALID_REQUEST", "Payment request is null");
        }

        String channelId = request.getChannelId();
        if (channelId == null || channelId.trim().isEmpty()) {
            throw new PaymentException("INVALID_REQUEST", "Channel ID is null or empty");
        }

        String implementationType = request.getImplementationType();
        logger.debug("开始创建支付，渠道: {}, 实现类型: {}, 订单号: {}", channelId, implementationType, request.getMerchantOrderId());

        // 获取可用渠道实现
        IPaymentChannel channel = getAvailableChannelImplementation(channelId, implementationType);

        // 创建支付
        PaymentResultDTO result = channel.createPayment(request);

        logger.debug("支付创建成功，渠道: {}, 实现类型: {}, 订单号: {}", channelId, implementationType, request.getMerchantOrderId());
        return result;
    }

    /**
     * 获取可用的渠道实现
     *
     * @param channelId 渠道ID
     * @param implementationType 实现类型，如果为null则使用默认实现
     * @return 渠道实例
     * @throws PaymentException 渠道不存在或不可用时抛出
     */
    private IPaymentChannel getAvailableChannelImplementation(String channelId, String implementationType) throws PaymentException {
        // 如果没有指定实现类型，使用默认实现
        if (implementationType == null || implementationType.trim().isEmpty()) {
            return paymentManager.getAvailableChannel(channelId);
        }

        // 尝试获取指定的实现
        String implementationKey = channelId + "_" + implementationType;
        IPaymentChannel channel = paymentManager.getChannelManager().getChannelImplementation(implementationKey);

        if (channel == null) {
            throw new PaymentException("CHANNEL_IMPLEMENTATION_NOT_FOUND",
                "Payment channel implementation not found: " + channelId + " with implementation: " + implementationType);
        }

        if (!channel.isAvailable()) {
            throw new PaymentException("CHANNEL_IMPLEMENTATION_UNAVAILABLE",
                "Payment channel implementation is not available: " + channelId + " with implementation: " + implementationType);
        }

        return channel;
    }

    /**
     * 查询支付状态
     *
     * @param request 查询请求
     * @return 查询结果
     * @throws PaymentException 查询失败时抛出
     */
    public QueryResultDTO queryPayment(QueryRequestDTO request) throws PaymentException {
        if (request == null) {
            throw new PaymentException("INVALID_REQUEST", "Query request is null");
        }

        String channelId = request.getChannelId();
        if (channelId == null || channelId.trim().isEmpty()) {
            throw new PaymentException("INVALID_REQUEST", "Channel ID is null or empty");
        }

        logger.debug("开始查询支付，渠道: {}, 订单号: {}", channelId, request.getMerchantOrderId());

        // 获取可用渠道
        IPaymentChannel channel = paymentManager.getAvailableChannel(channelId);

        // 查询支付
        QueryResultDTO result = channel.queryPayment(request);

        logger.debug("支付查询成功，渠道: {}, 订单号: {}, 状态: {}",
            channelId, request.getMerchantOrderId(), result.getStatus());
        return result;
    }

    /**
     * 关闭支付订单
     *
     * @param channelId 渠道ID
     * @param orderId 订单ID
     * @return 是否成功关闭
     * @throws PaymentException 关闭失败时抛出
     */
    public boolean closePayment(String channelId, String orderId) throws PaymentException {
        if (channelId == null || channelId.trim().isEmpty()) {
            throw new PaymentException("INVALID_REQUEST", "Channel ID is null or empty");
        }

        if (orderId == null || orderId.trim().isEmpty()) {
            throw new PaymentException("INVALID_REQUEST", "Order ID is null or empty");
        }

        logger.debug("开始关闭支付，渠道: {}, 订单号: {}", channelId, orderId);

        // 获取可用渠道
        IPaymentChannel channel = paymentManager.getAvailableChannel(channelId);

        // 关闭支付
        boolean result = channel.closePayment(orderId);

        logger.debug("支付关闭{}，渠道: {}, 订单号: {}",
            result ? "成功" : "失败", channelId, orderId);
        return result;
    }

    /**
     * 处理支付回调
     *
     * @param channelId 渠道ID
     * @param callbackData 回调数据
     * @return 处理结果
     * @throws PaymentException 处理失败时抛出
     */
    public PaymentResultDTO processCallback(String channelId, String callbackData) throws PaymentException {
        if (channelId == null || channelId.trim().isEmpty()) {
            throw new PaymentException("INVALID_REQUEST", "Channel ID is null or empty");
        }

        if (callbackData == null || callbackData.trim().isEmpty()) {
            throw new PaymentException("INVALID_REQUEST", "Callback data is null or empty");
        }

        logger.debug("开始处理支付回调，渠道: {}", channelId);

        // 获取可用渠道
        IPaymentChannel channel = paymentManager.getAvailableChannel(channelId);

        // 验证回调
        boolean verified = channel.verifyCallback(callbackData);
        if (!verified) {
            throw new PaymentException("CALLBACK_VERIFY_FAILED", "Callback verification failed", channelId);
        }

        // 处理回调
        PaymentResultDTO result = channel.processCallback(callbackData);

        logger.debug("支付回调处理成功，渠道: {}, 订单状态: {}", channelId, result.getStatus());
        return result;
    }

    /**
     * 获取渠道信息
     *
     * @param channelId 渠道ID
     * @return 渠道信息
     */
    public PaymentChannelManager.ChannelInfo getChannelInfo(String channelId) {
        return paymentManager.getChannelInfo(channelId);
    }

    /**
     * 获取所有渠道信息
     *
     * @return 渠道信息数组
     */
    public PaymentChannelManager.ChannelInfo[] getAllChannelInfo() {
        return paymentManager.getAllChannelInfo();
    }

    /**
     * 获取所有增强渠道信息（包括多实现）
     *
     * @return 增强渠道信息数组
     */
    public PaymentChannelManager.EnhancedChannelInfo[] getAllEnhancedChannelInfo() {
        return paymentManager.getAllEnhancedChannelInfo();
    }

    /**
     * 获取所有渠道实现信息（按注册顺序）
     *
     * @return 渠道实现信息数组
     */
    public PaymentChannelManager.ChannelImplementationInfo[] getAllChannelImplementationInfoInOrder() {
        return paymentManager.getAllChannelImplementationInfoInOrder();
    }

    /**
     * 获取可用渠道ID列表
     *
     * @return 可用渠道ID数组
     */
    public String[] getAvailableChannelIds() {
        return paymentManager.getAvailableChannelIds();
    }

    /**
     * 检查渠道是否可用
     *
     * @param channelId 渠道ID
     * @return 是否可用
     */
    public boolean isChannelAvailable(String channelId) {
        return paymentManager.isChannelAvailable(channelId);
    }

    /**
     * 获取渠道支持的支付产品
     *
     * @param channelId 渠道ID
     * @return 支付产品数组
     * @throws PaymentException 渠道不存在时抛出
     */
    public String[] getSupportedPayMethods(String channelId) throws PaymentException {
        IPaymentChannel channel = paymentManager.getAvailableChannel(channelId);
        return channel.getSupportedPayProducts();
    }

    /**
     * 获取渠道配置模板
     *
     * @param channelId 渠道ID
     * @return 配置模板
     * @throws PaymentException 渠道不存在时抛出
     */
    public String getChannelConfigTemplate(String channelId) throws PaymentException {
        IPaymentChannel channel = paymentManager.getAvailableChannel(channelId);
        return channel.getConfigTemplate();
    }

    /**
     * 获取渠道的实现类型列表
     *
     * @param channelId 渠道ID
     * @return 实现类型列表
     */
    public String[] getChannelImplementationTypes(String channelId) {
        java.util.List<String> implementations = paymentManager.getChannelFactory().getChannelImplementations(channelId);
        return implementations != null ? implementations.toArray(new String[0]) : new String[0];
    }

    /**
     * 获取渠道的默认实现类型
     *
     * @param channelId 渠道ID
     * @return 默认实现类型
     */
    public String getChannelDefaultImplementation(String channelId) {
        return paymentManager.getChannelFactory().getDefaultImplementation(channelId);
    }

    /**
     * 获取所有渠道的实现信息
     *
     * @return 渠道实现信息映射
     */
    public java.util.Map<String, ChannelImplementationInfo> getAllChannelImplementationInfo() {
        java.util.Map<String, ChannelImplementationInfo> result = new java.util.HashMap<>();

        java.util.Map<String, java.util.List<String>> allImplementations = paymentManager.getChannelFactory().getAllChannelImplementations();
        java.util.Map<String, String> defaultImplementations = paymentManager.getChannelFactory().getAllDefaultImplementations();

        for (java.util.Map.Entry<String, java.util.List<String>> entry : allImplementations.entrySet()) {
            String channelId = entry.getKey();
            java.util.List<String> implementations = entry.getValue();
            String defaultImpl = defaultImplementations.get(channelId);

            ChannelImplementationInfo info = new ChannelImplementationInfo(
                channelId,
                implementations,
                defaultImpl
            );
            result.put(channelId, info);
        }

        return result;
    }

    /**
     * 打印所有渠道实现信息
     */
    public void printAllChannelImplementationInfo() {
        logger.debug("=== 所有渠道实现信息 ===");

        java.util.Map<String, ChannelImplementationInfo> allInfo = getAllChannelImplementationInfo();

        for (java.util.Map.Entry<String, ChannelImplementationInfo> entry : allInfo.entrySet()) {
            ChannelImplementationInfo info = entry.getValue();
            logger.debug("渠道: {}", info.getChannelId());
            logger.debug("  支持的实现类型: {}", String.join(", ", info.getImplementations()));
            logger.debug("  默认实现: {}", info.getDefaultImplementation());
            logger.debug("  实现数量: {}", info.getImplementationCount());
            logger.debug("  是否支持多实现: {}", info.hasMultipleImplementations());
            logger.debug("---");
        }

        logger.debug("=== 渠道实现信息打印完成 ===");
    }

    /**
     * 渠道实现信息类
     */
    public static class ChannelImplementationInfo {
        private final String channelId;
        private final java.util.List<String> implementations;
        private final String defaultImplementation;

        public ChannelImplementationInfo(String channelId, java.util.List<String> implementations, String defaultImplementation) {
            this.channelId = channelId;
            this.implementations = implementations;
            this.defaultImplementation = defaultImplementation;
        }

        public String getChannelId() {
            return channelId;
        }

        public java.util.List<String> getImplementations() {
            return implementations;
        }

        public String getDefaultImplementation() {
            return defaultImplementation;
        }

        public int getImplementationCount() {
            return implementations != null ? implementations.size() : 0;
        }

        public boolean hasMultipleImplementations() {
            return getImplementationCount() > 1;
        }

        @Override
        public String toString() {
            return "ChannelImplementationInfo{" +
                    "channelId='" + channelId + '\'' +
                    ", implementations=" + implementations +
                    ", defaultImplementation='" + defaultImplementation + '\'' +
                    '}';
        }
    }
}